/**
 * 
 */
package cn.edu.cqu.bysj.wm.ago.anlys;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.Node;

import cn.edu.cqu.bysj.wm.ago.lp.LPCommunity;
import cn.edu.cqu.bysj.wm.def.ConstDef;
import cn.edu.cqu.bysj.wm.neo4j.Neo4jTraversal;

/**
 * @author Meng
 * 
 */
public class Cluster {

	// community id vs cluster coefficient value
	public static Map<Long, Double> clusterCoefficients;

	/**
	 * 
	 * @param direction
	 *            graph direction
	 * @param type
	 *            algorithm GN or LP
	 */
	public static void calculate(Direction direction, int type) {

		clusterCoefficients = new HashMap<Long, Double>();

		Map<Long, List<Node>> communitys;
		if (type == ConstDef.LP) {
			communitys = LPCommunity.communitys;
		} else {
			communitys = ModularityGN.result;
		}

		// each community , calculate cluster coefficient
		for (long cid : communitys.keySet()) {

			List<Node> nodes = communitys.get(cid);

			// each node in community cid, calculate cluster coefficient
			double ans = 0d;
			for (Node node : nodes) {

				// conected nodes to node
				List<Node> list = Neo4jTraversal.getAdjoinedNodes(node, nodes,
						direction);
				int k = list.size();

				// calculate actually exist edges in the local net from node
				if (list.size() > 1) {
					int num = Neo4jTraversal
							.getEdgesInAdjoinedNodes(node, list).size();

					// cluster coefficient definition
					double cc = 2d * num / (k * (k - 1));
					// for directed graph
					if (!direction.equals(Direction.BOTH)) {
						cc /= 2;
					}
					ans += cc;
				}
			}
			// average cluster coefficient in the community
			ans /= nodes.size();
			clusterCoefficients.put(cid, ans);
		}
	}

}
